# 本脚本用于绘制 CPU 序列和三种流水线基准测试的请求吞吐量对比
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
import os

# 设置绘图风格
plt.style.use('seaborn-v0_8-whitegrid')

# 读取结果数据
results_dir = '../results_raw/pipeline_case_study'

# 读取序列处理数据
sequence_csv = os.path.join(results_dir, 'sequence_throughput.csv')
seq_df = pd.read_csv(sequence_csv).sort_values('batch_size')

# 读取原始流水线处理数据
pipeline_csv = os.path.join(results_dir, 'pipeline_local_device.csv')
pipe_df = pd.read_csv(pipeline_csv).sort_values('batch_size')

# 读取跨架构流水线数据
cross_csv = os.path.join(results_dir, 'pipeline_cross_tuopu.csv')
cross_df = pd.read_csv(cross_csv).sort_values('batch_size')

# 读取跨设备流水线数据（新增1）
cross_dev_csv = os.path.join(results_dir, 'pipeline_local_1core.csv')
cross_dev_df = pd.read_csv(cross_dev_csv).sort_values('batch_size')
cross_dev_df['request_throughput_rps_p50'] *= 8  # 乘以8倍

# 读取跨多设备流水线数据（新增2）
cross_dev2_csv = os.path.join(results_dir, 'pipeline_cross_device.csv')
cross_dev2_df = pd.read_csv(cross_dev2_csv).sort_values('batch_size')

# 设置最大 batch size 限制
max_cross_bs = 2**17
cross_filtered = cross_df[cross_df['batch_size'] <= max_cross_bs]
cross_dev_filtered = cross_dev_df[cross_dev_df['batch_size'] <= max_cross_bs]
cross_dev2_filtered = cross_dev2_df[cross_dev2_df['batch_size'] <= max_cross_bs]

# 创建图形
plt.figure(figsize=(14, 9))

# 绘制序列处理吞吐量 (蓝色)
plt.plot(seq_df['batch_size'], seq_df['request_throughput_rps_p50'], 
         marker='o', markersize=8, linewidth=2.5, 
         color='#1f77b4', label='Sequence Throughput (1 CPU core)')

# 绘制原始流水线处理吞吐量 (橙色)
plt.plot(pipe_df['batch_size'], pipe_df['request_throughput_rps_p50'], 
         marker='s', markersize=8, linewidth=2.5, linestyle='--',
         color='#ff7f0e', label='Pipeline Throughput (only host: 3-stage, 1 core/stage)')

# 绘制跨架构流水线吞吐量 (绿色)
plt.plot(cross_filtered['batch_size'], cross_filtered['request_throughput_rps_p50'], 
         marker='^', markersize=8, linewidth=2.5, linestyle='-.',
         color='#2ca02c', label='tuopu cross Throughput (1 core CPU + 1 core ARM + 16 core DPA)')

# 绘制跨设备流水线吞吐量 (紫色)
plt.plot(cross_dev_filtered['batch_size'], cross_dev_filtered['request_throughput_rps_p50'], 
         marker='D', markersize=8, linewidth=2.5, linestyle=':',
         color='#9467bd', label='Pipeline Throughput (only host: 1-stage, 8-core)')

# 绘制跨多设备流水线吞吐量 (红色)
plt.plot(cross_dev2_filtered['batch_size'], cross_dev2_filtered['request_throughput_rps_p50'], 
         marker='X', markersize=8, linewidth=2.5, linestyle='--',
         color='#d62728', label='Pipeline Throughput (cross-device)')

# 设置对数坐标轴
plt.xscale('log', base=2)
plt.yscale('log')

# 设置刻度标记
batch_sizes = sorted(set(seq_df['batch_size']).union(pipe_df['batch_size']).union(cross_df['batch_size']).union(cross_dev_df['batch_size']).union(cross_dev2_df['batch_size']))
plt.xticks(batch_sizes, labels=[f"{size:,}" for size in batch_sizes], rotation=45)
plt.yticks([10**i for i in range(3, 9)], labels=[f"10^{i}" for i in range(3, 9)])

# 添加数据标签 - 序列处理
for i, (bs, thr) in enumerate(zip(seq_df['batch_size'], seq_df['request_throughput_rps_p50'])):
    if i % 2 == 0:
        plt.annotate(f"{thr/1e6:.1f}M", (bs, thr), 
                     textcoords="offset points", xytext=(0,10), 
                     ha='center', fontsize=9, color='#1f77b4')

# 添加数据标签 - 原始流水线处理
for i, (bs, thr) in enumerate(zip(pipe_df['batch_size'], pipe_df['request_throughput_rps_p50'])):
    if i % 2 == 1:
        plt.annotate(f"{thr/1e6:.1f}M", (bs, thr), 
                     textcoords="offset points", xytext=(0,-15), 
                     ha='center', fontsize=9, color='#ff7f0e')

# 添加数据标签 - 跨架构流水线处理
for i, (bs, thr) in enumerate(zip(cross_filtered['batch_size'], cross_filtered['request_throughput_rps_p50'])):
    offset = 10 if i % 2 == 0 else -15
    plt.annotate(f"{thr/1e6:.1f}M", (bs, thr), 
                 textcoords="offset points", xytext=(0, offset), 
                 ha='center', fontsize=9, color='#2ca02c')

# 添加数据标签 - 跨设备流水线处理
for i, (bs, thr) in enumerate(zip(cross_dev_filtered['batch_size'], cross_dev_filtered['request_throughput_rps_p50'])):
    offset = 15 if i % 2 == 0 else -20
    plt.annotate(f"{thr/1e6:.1f}M", (bs, thr), 
                 textcoords="offset points", xytext=(0, offset), 
                 ha='center', fontsize=9, color='#9467bd')

# 添加数据标签 - 跨多设备流水线处理
for i, (bs, thr) in enumerate(zip(cross_dev2_filtered['batch_size'], cross_dev2_filtered['request_throughput_rps_p50'])):
    offset = 10 if i % 2 == 0 else -10
    plt.annotate(f"{thr/1e6:.1f}M", (bs, thr), 
                 textcoords="offset points", xytext=(0, offset), 
                 ha='center', fontsize=9, color='#d62728')

# 添加标题和标签
plt.title('Request Throughput Comparison: Sequence vs Multiple Pipeline Architectures', fontsize=16, pad=20)
plt.xlabel('Batch Size (log scale)', fontsize=14, labelpad=10)
plt.ylabel('Request Throughput (requests/sec, log scale)', fontsize=14, labelpad=10)

# 添加网格和图例
plt.grid(True, which="both", ls='--', alpha=0.7)
plt.legend(fontsize=12, loc='best')

# 调整布局
plt.tight_layout()

# 保存图像
plot_file = os.path.join(results_dir, 'throughput_comparison_multiple_architectures.png')
plt.savefig(plot_file, dpi=300, bbox_inches='tight')
print(f"对比图已保存到: {plot_file}")

# 显示图像
plt.show()
